package com.lzp.java.jdk8.lambda.c3;

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.springframework.test.util.AssertionErrors.assertEquals;
import static org.springframework.test.util.AssertionErrors.assertTrue;

/**
 * @description: 使用Stream替换for循环，实现内部迭代
 * @author: lzp
 * @createTime: 2021-07-12 07:24
 **/
public class StreamAPI {
    public static void main(String[] args) {
        List<String> list = new ArrayList<>();
        list.add("ll");
        list.add("zz");
        list.add("ll");
        // for-each
        int count = 0;
        for (String s : list) {
            if ("zz".equals(s)) {
                count++;
            }
        }
        // 外部迭代
        int count1 = 0;
        Iterator<String> iterator = list.iterator();
        while (iterator.hasNext()) {
            String next = iterator.next();
            if ("zz".equals(next)) {
                count1++;
            }
        }
        // 使用stream内部迭代
        // filter 过滤
        long count2 = list.stream()
                .filter(e -> "zz".equals(e))
                .count();
        assertTrue("filter", 1 == count2);
        // of 使用初始值生成一个流
        // collect 从流生成一个集合
        List<String> collect = Stream.of("a", "b", "b").filter(e -> "b".equals(e))
                .collect(Collectors.toList());
        assertEquals("生成新的list", Arrays.asList("b", "b"), collect);

        // map 将一个流中的值转换为一个新的流
        List<String> list1 = new ArrayList<>();
        for (String s : Arrays.asList("a", "b", "c")) {
            list1.add(s.toUpperCase());
        }
        assertEquals("", Arrays.asList("A", "B", "C"), list1);
        List<String> list2 = Stream.of("a", "b", "c").map(e -> e.toUpperCase())
                .collect(Collectors.toList());
        assertEquals("使用map转换流", Arrays.asList("A", "B", "C"), list2);

        // flatMap 合成多个流
        List<String> together = Stream.of(Arrays.asList("a", "b"), Arrays.asList("c"))
                .flatMap(e -> e.stream()).collect(Collectors.toList());
        assertEquals("flatMap", Arrays.asList("a", "b", "c"), together);

        // max/min 求最大/最小 get获取值
        List<Track> tracks = Arrays.asList(new Track("lzp", 15), new Track("dtyy", 20));
        Track minTrack = tracks.stream()
                .min(Comparator.comparing(track -> track.age))
                .get();
        assertTrue("min", 15 == minTrack.age);

        // reduce 归约操作，从一组值中生成一个值
        int count3 = Stream.of(1, 2, 3).reduce(0, (x1, x2) -> x1 + x2);
        int count4 = Stream.of(1, 2, 3).reduce(0, Integer::sum);
        assertTrue("reduce", 6 == count3);
    }

    static class Track {
        String name;
        Integer age;

        public Track(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
    }
}
